#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <sqlite3.h>
#import <UIKit/UIApplication.h>

#import "framework/FWCommon.h"

#import "PIListAccess.h"
#import "PITodoPreview.h"
#import "PIIntegration.h"


@implementation PITodoPreview


// ******************************************************************************************
#pragma mark -
#pragma mark Handling user input

- (BOOL)doneClicked:(FWApplication*)application sections:(NSArray*)sections
{
    return YES;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Accessing records from the database

static NSInteger const kDetailPageLookup = 1;
static NSInteger const kLinkPageLookup = 2;

- (NSString*)captionForListPage:(NSObject *)page forKey:(NSNumber *)key displayDepth:(NSInteger)depth application:(FWApplication *)application
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    NSDictionary* element = [(NSArray*)page objectAtIndex:0];
    NSNumber* isChild = [element objectForKey:kPIListAccessFieldIsChild];
    NSNumber* isParent = [element objectForKey:kPIListAccessFieldIsParent];

    if ([isChild intValue])
         return localize(bundle, @"Detail/Child");
    else if ([isParent intValue])
         return localize(bundle, @"Detail/Parent");
    else
        return @"";
}

- (NSArray*)dataForDetailListPage:(NSObject *)page application:(FWApplication *)application
{
    NSDictionary* elem = (NSDictionary*)page;
    NSNumber* key = [elem objectForKey:kPIListAccessFieldKey];
    NSNumber* parent = [elem objectForKey:@"parent"];
    if (!parent)
        parent = key;
    
    NSString* sql = [NSString stringWithFormat:@"select t.title, t.startdate, t.duedate, t.duedatetime, t.priority, t.fcpriority, t.flagged, t.action, t.icon, t.notes, t.percentcomplete, a.title, c.name, p.title, t.calendarid, k.title, t.id, t.parenttaskid,"
                     " (select count(*) from task where parenttaskid = t.id),"
                     " group_concat(g.title, ', ')"
                                                " from task t"
                                                " left join task a on t.parenttaskid = a.id"
                                                " left join context c on t.contextid = c.id"
                                                " left join calendar k on t.calendarid = k.id"
                                                " left join task p on t.projectid = p.id"
                                                " left join itemtagmap m on m.itemid = t.id"
                                                " left join tag g on m.tagid = g.id"
                                                " where t.id = %@"
                                                " order by g.title", [key stringValue]];

    NSArray* record = FWDBGetRecords(sql, kDetailPageLookup, application.databasePath, application, self);
    record = [record objectAtIndex:0];
    
    for (NSDictionary* sect in record) {
        NSArray* elements = [sect objectForKey:FWDetailListViewSectionContents];
        for (NSMutableDictionary* element in elements) {
            if (NSNumber* link = [element objectForKey:FWDetailListViewFieldIsLink]) {
                if ([link intValue] == [parent intValue]) {
                    [element removeObjectForKey:FWDetailListViewFieldIsLink];
                    [element setValue:parent forKey:FWDetailListViewFieldIsBackLink];
                }
            }
        }
    }
    
    return record;
}

- (NSArray*)listPageInfoForKey:(NSNumber*)key currentPage:(NSObject *)current displayDepth:(NSInteger)depth application:(FWApplication *)application
{
    NSDictionary* page = (NSDictionary*)current;
    NSNumber* parent = [page objectForKey:kPIListAccessFieldKey];
    NSNumber* isChild = [page objectForKey:kPIListAccessFieldIsChild];
    NSNumber* isParent = [page objectForKey:kPIListAccessFieldIsParent];
    
    NSDictionary* elem = [NSDictionary dictionaryWithObjectsAndKeys:key, kPIListAccessFieldKey,
                          [NSNumber numberWithInt:depth], @"depth",
                          [NSNumber numberWithInt:[isChild intValue] == 0], kPIListAccessFieldIsChild,
                          [NSNumber numberWithInt:[isParent intValue] == 0], kPIListAccessFieldIsParent,
                          parent, @"parent", nil];

    return [NSArray arrayWithObject:elem];
}

- (NSObject*)taskObjectForSQLRecord:(sqlite3_stmt*)sqlStatement application:(FWApplication*)application 
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    
    const char *cTitle = (const char*)sqlite3_column_text(sqlStatement, 0);
    double cStart = sqlite3_column_double(sqlStatement, 1);
    double cDue = sqlite3_column_double(sqlStatement, 2);
    double cDueTime = sqlite3_column_double(sqlStatement, 3);
    int cImportance = sqlite3_column_int(sqlStatement, 4);
    const char *cPriority = (const char*)sqlite3_column_text(sqlStatement, 5);
    BOOL cFlagged = sqlite3_column_int(sqlStatement, 6) != 0;
    int cAction = sqlite3_column_int(sqlStatement, 7);
    const char *cIcon = (const char*)sqlite3_column_text(sqlStatement, 8);
    const char *cNote = (const char*)sqlite3_column_text(sqlStatement, 9);
    int cPercentComplete = sqlite3_column_int(sqlStatement, 10);
    const char *cParent = (const char*)sqlite3_column_text(sqlStatement, 11);
    const char *cContext = (const char*)sqlite3_column_text(sqlStatement, 12);
    const char *cProject = (const char*)sqlite3_column_text(sqlStatement, 13);
    int cCalendarID = sqlite3_column_int(sqlStatement, 14);
    const char *cCalendar = (const char*)sqlite3_column_text(sqlStatement, 15);
    int cTaskID = sqlite3_column_int(sqlStatement, 16);
    int cParentTaskID = sqlite3_column_int(sqlStatement, 17);
    BOOL cIsParent = sqlite3_column_int(sqlStatement, 18) != 0;
    const char *cTags = (const char*)sqlite3_column_text(sqlStatement, 20);
    
    NSString* icon = [NSString stringWithUTF8String:(cIcon == NULL ? "" : cIcon)];
    NSString* title = [NSString stringWithUTF8String:(cTitle == NULL ? "" : cTitle)];
    
    if ([icon length] > 0)
        title = [NSString stringWithFormat:@"%@ %@", title, icon];
    
    NSMutableDictionary* titleRows = [NSMutableDictionary dictionaryWithCapacity:3];
    [titleRows setObject:title
                  forKey:FWDetailListViewFieldTitle];
    if (cFlagged) {
        NSString* iconFile = [PIIntegration iconPathForLargeFlag:application];// [application.applicationPath stringByAppendingString:@"/star_yellow.png"];
        UIImage* icon = [UIImage imageWithContentsOfFile:iconFile];
        if (icon != nil)
            [titleRows setObject:icon forKey:FWDetailListViewFieldIcon];
    }
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        [titleRows setObject:[NSNumber numberWithFloat:([UIFont labelFontSize] + 3.0)]
                      forKey:FWDetailListViewFieldSize];
    else
        [titleRows setObject:[NSNumber numberWithFloat:([UIFont labelFontSize] * 2)]
                      forKey:FWDetailListViewFieldSize];
    
    NSArray* titleSect = [NSArray arrayWithObjects:
                          titleRows,
                          nil];
    
    BOOL overdue = NO;
    UIColor* dateBG = [UIColor whiteColor];
    double duetime = cDueTime != 0 ? cDueTime : cDue;
    if (duetime != 0) {
        BOOL timeElement = (cDueTime != 0);
        NSDate* dueDate =  timeElement ? [PIIntegration localDateForTimeNumber:[NSNumber numberWithDouble:duetime]]
        : [PIIntegration localDateForDateNumber:[NSNumber numberWithDouble:duetime]];
        NSDate *today = [NSDate date];
        if ([dueDate compare:today] == NSOrderedAscending) {
            overdue = YES;
            dateBG = [PIIntegration colorForOverdue:application];
        }
    }
    
    // Dates section
    NSMutableArray* datesSect = [NSMutableArray arrayWithCapacity:2];
    if (cStart != 0) {
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          localize(bundle, @"Detail/Start"), FWDetailListViewFieldTitle,
          [PIIntegration dateStringForDateNumber:[NSNumber numberWithDouble:cStart]
                                        withTime:false
                                          format:DateFormatterLongFormat], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
#ifdef DEBUG
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          @"Start Date*", FWDetailListViewFieldTitle,
          [NSString stringWithFormat:@"%@", [[[NSDate alloc] initWithTimeIntervalSinceReferenceDate:cStart] autorelease]], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          @"Start Date*", FWDetailListViewFieldTitle,
          [NSString stringWithFormat:@"%F", cStart], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
#endif
    }
    if (cDueTime != 0) {
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          localize(bundle, @"Detail/Due"), FWDetailListViewFieldTitle,
          [PIIntegration dateStringForDateNumber:[NSNumber numberWithDouble:cDueTime]
                                        withTime:true
                                          format:DateFormatterLongFormat], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
#ifdef DEBUG
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          @"Due Time*", FWDetailListViewFieldTitle,
          [NSString stringWithFormat:@"%@", [[[NSDate alloc] initWithTimeIntervalSinceReferenceDate:cDueTime] autorelease]], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          @"Due Time*", FWDetailListViewFieldTitle,
          [NSString stringWithFormat:@"%F", cDueTime], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
#endif
    }
    else if (cDue != 0) {
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          localize(bundle, @"Detail/Due"), FWDetailListViewFieldTitle,
          [PIIntegration dateStringForDateNumber:[NSNumber numberWithDouble:cDue]
                                        withTime:false
                                          format:DateFormatterLongFormat], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
#ifdef DEBUG
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          @"Due Date*", FWDetailListViewFieldTitle,
          [NSString stringWithFormat:@"%@", [[[NSDate alloc] initWithTimeIntervalSinceReferenceDate:cDue] autorelease]], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
        [datesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          @"Due Date*", FWDetailListViewFieldTitle,
          [NSString stringWithFormat:@"%F", cDue], FWDetailListViewFieldValue,
          dateBG, FWDetailListViewFieldBGColor,
          nil]];
#endif
    }					
    
//    if (overdue) 
//        [datesSect addObject:
//         [NSDictionary dictionaryWithObjectsAndKeys:
//          localize(bundle, @"Detail/Overdue"), FWDetailListViewFieldMessage,
//          [NSNumber numberWithFloat:([UIFont labelFontSize] + 3.0)], FWDetailListViewFieldSize,
//          dateBG, FWDetailListViewFieldBGColor,
//          nil]];
    
    // Context section
    NSMutableArray* contextSect = [NSMutableArray arrayWithCapacity:3];
#ifdef DEBUG
    [contextSect addObject:
     [NSDictionary dictionaryWithObjectsAndKeys:
      @"ID", FWDetailListViewFieldTitle,
      [NSString stringWithFormat:@"%i", cTaskID], FWDetailListViewFieldValue,
      nil]];
#endif
    
    NSString* context = [NSString stringWithUTF8String:(cContext == NULL ? "" : cContext)];
    if ([context length] > 0)
        [contextSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          localize(bundle, @"Detail/Context"), FWDetailListViewFieldTitle,
          context, FWDetailListViewFieldValue,
          nil]];
    
    NSString* project = [NSString stringWithUTF8String:(cProject == NULL ? "" : cProject)];
    if ([project length] > 0)
        [contextSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          localize(bundle, @"Detail/Project"), FWDetailListViewFieldTitle,
          project, FWDetailListViewFieldValue,
          nil]];
    
    NSString* tags = [NSString stringWithUTF8String:(cTags == NULL ? "" : cTags)];
    if ([tags length] > 0)
        [contextSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          localize(bundle, @"Detail/Tags"), FWDetailListViewFieldTitle,
          tags, FWDetailListViewFieldValue,
          nil]];
    
    //NSString* parent = [NSString stringWithUTF8String:(cParent == NULL ? "" : cParent)];
    //if ([parent length] > 0)
    //    [contextSect addObject:
    //     [NSDictionary dictionaryWithObjectsAndKeys:
    //      localize(bundle, @"Detail/Parent"), FWDetailListViewFieldTitle,
    //      parent, FWDetailListViewFieldValue,
    //      nil]];
    
    NSString* calendar = [NSString stringWithUTF8String:(cCalendar == NULL ? "" : cCalendar)];
    if (cCalendarID == -2)
        calendar = localize(bundle, @"Detail/Internal Task Calendar");
    if ([calendar length] > 0)
        [contextSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          localize(bundle, @"Detail/Calendar"), FWDetailListViewFieldTitle,
          calendar, FWDetailListViewFieldValue,
          nil]];
    
    
    // Progress section
    NSMutableArray* progressSect = [NSMutableArray arrayWithCapacity:4];
    [progressSect addObject:
     [NSDictionary dictionaryWithObjectsAndKeys:
      localize(bundle, @"Detail/Action"), FWDetailListViewFieldTitle,
      localize(bundle, [PIIntegration nameForAction:cAction]), FWDetailListViewFieldValue,
      nil]];
    
    NSString* importance = localize(bundle, [PIIntegration nameForImportance:cImportance]);
    NSString* priority = [NSString stringWithUTF8String:(cPriority == NULL ? "" : cPriority)];
    if ([priority length] > 0) {
        priority = [NSString stringWithFormat:@"%@\n%@", priority, importance];
        NSString* title = [NSString stringWithFormat:@"%@\n%@", localize(bundle, @"Detail/Priority"), localize(bundle, @"Detail/Importance")];
        
        [progressSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          title, FWDetailListViewFieldTitle,
          priority, FWDetailListViewFieldValue,
          [NSNumber numberWithInt:2], FWDetailListViewFieldLines,
          nil]];
    }
    else {
        [progressSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          localize(bundle, @"Detail/Importance"), FWDetailListViewFieldTitle,
          importance, FWDetailListViewFieldValue,
          nil]];
    }
    
    [progressSect addObject:
     [NSDictionary dictionaryWithObjectsAndKeys:
      [NSString stringWithFormat:localize(bundle, @"Detail/Complete"), cPercentComplete], FWDetailListViewFieldTitle,
      //      [NSString stringWithFormat:@"%i%%", cPercentComplete], FWDetailListViewFieldValue,
      [NSNumber numberWithFloat:(cPercentComplete / 100.0)], FWDetailListViewFieldProgress,
      nil]];
    
    
    // Notes section
    NSMutableArray* notesSect = [NSMutableArray arrayWithCapacity:1];
    NSString* note = [NSString stringWithUTF8String:(cNote == NULL ? "" : cNote)];
    if ([note length] > 0)
        [notesSect addObject:
         [NSDictionary dictionaryWithObjectsAndKeys:
          note, FWDetailListViewFieldTitle,
          [NSNumber numberWithBool:YES], FWDetailListViewFieldNoBold,
          [NSNumber numberWithFloat:[UIFont systemFontSize]], FWDetailListViewFieldSize,
          nil]];

    
    // Children/parent section
    NSDictionary* relationsSect = nil;
//    [relationsSect addObject:
//     [NSDictionary dictionaryWithObjectsAndKeys:
//      @"Link", FWDetailListViewFieldTitle,
//      [NSNumber numberWithInt:1], FWDetailListViewFieldIsLink,
//      nil]];
//    
    if (cIsParent) {
        // Fetch child elements
        NSString* sql = [NSString stringWithFormat:@"select title, icon, flagged, id"
                         " from task"
                         " where parenttaskid = %i and tasktype <> 1 and completeddate is null and (calendarid=-2 or calendarid>=0)"
                         " order by sortfield",
                         cTaskID];

        NSArray* children = FWDBGetRecords(sql, kLinkPageLookup, application.databasePath, application, self);
        if ([children count] > 0)
            relationsSect = [FWDetailListView sectionEntryForElements:children 
                                                            withTitle:localize(bundle, @"Detail/Children")];
    }
    else if (cParentTaskID > 0) {
        // Fetch parent element
        NSString* sql = [NSString stringWithFormat:@"select title, icon, flagged, id"
                         " from task"
                         " where id = %i",
                         cParentTaskID];
        
        NSArray* parent = FWDBGetRecords(sql, kLinkPageLookup, application.databasePath, application, self);
        if ([parent count] > 0)
            relationsSect = [FWDetailListView sectionEntryForElements:parent 
                                                            withTitle:localize(bundle, @"Detail/Parent")];
    }
    
    // Build sections list
    NSMutableArray* sects = [NSMutableArray arrayWithCapacity:6];
    [sects addObject:[FWDetailListView sectionEntryForElements:titleSect]];
    if ([datesSect count] > 0)
        [sects addObject:[FWDetailListView sectionEntryForElements:datesSect]];
    if ([contextSect count] > 0)
        [sects addObject:[FWDetailListView sectionEntryForElements:contextSect]];
    if ([progressSect count] > 0)
        [sects addObject:[FWDetailListView sectionEntryForElements:progressSect]];
    if (relationsSect)
        [sects addObject:relationsSect];
    if ([notesSect count] > 0)
        [sects addObject:[FWDetailListView sectionEntryForElements:notesSect
                                                         withTitle:localize(bundle, @"Detail/Notes")]];
    DebugLog(@"LI:PITodo: Detail read = %@", sects);
    
    return sects;
}

- (NSObject*)relationObjectForSQLRecord:(sqlite3_stmt*)sqlStatement application:(FWApplication*)application 
{
    const char *cTitle = (const char*)sqlite3_column_text(sqlStatement, 0);
    const char *cIcon = (const char*)sqlite3_column_text(sqlStatement, 1);
    BOOL cFlagged = sqlite3_column_int(sqlStatement, 2) != 0;
    int cTaskID = sqlite3_column_int(sqlStatement, 3);

    NSString* title = [NSString stringWithUTF8String:(cTitle == NULL ? "" : cTitle)];
    NSString* icon = [NSString stringWithUTF8String:(cIcon == NULL ? "" : cIcon)];
    
    if ([icon length] > 0)
        title = [NSString stringWithFormat:@"%@ %@", title, icon];
    
    NSMutableDictionary* titleRows = [NSMutableDictionary dictionaryWithCapacity:3];
    [titleRows setObject:title
                  forKey:FWDetailListViewFieldTitle];
    [titleRows setObject:[NSNumber numberWithInt:cTaskID]
                  forKey:FWDetailListViewFieldIsLink];

     if (cFlagged) {
        NSString* iconFile = [PIIntegration iconPathForLargeFlag:application];//[application.applicationPath stringByAppendingString:@"/star_yellow.png"];
        UIImage* icon = [UIImage imageWithContentsOfFile:iconFile];
        if (icon != nil)
            [titleRows setObject:icon forKey:FWDetailListViewFieldIcon];
    }
    
    DebugLog(@"LI:PITodo: Relation read = %@", titleRows);
    
    return titleRows;
}

- (NSObject*)objectForSQLRecord:(sqlite3_stmt*)sqlStatement withId:(NSInteger)sqlid application:(FWApplication*)application 
{
    if (sqlid == kDetailPageLookup)
        return [self taskObjectForSQLRecord:sqlStatement application:application];
    else
        return [self relationObjectForSQLRecord:sqlStatement application:application];
}

@end
